﻿using StackExchange.Redis;

Console.WriteLine();
Console.WriteLine("~~Garnet Command Tool for Garnet / Redis~~");
Console.WriteLine();

Begin:
string ip = "127.0.0.1";
Console.WriteLine($"Input host IP(default {ip}):");
var s = Console.ReadLine();
if (!string.IsNullOrWhiteSpace(s))
    ip = s.Trim();

int port = 3278;
Console.WriteLine($"Input host Port(default {port}):");
s = Console.ReadLine();
if (!string.IsNullOrWhiteSpace(s))
    port = int.Parse(s.Trim());

ConnectionMultiplexer redis;
IDatabase db;
try
{
    redis = ConnectionMultiplexer.Connect($"{ip}:{port}");
    db = redis.GetDatabase();
    Console.WriteLine("Connected to host successfully! ");
}
catch
{
    Console.WriteLine("Failed to connect to host!");
    Console.WriteLine("Please try again");
    goto Begin;
}

string? line = string.Empty;
while (line != "q")
{
    Console.WriteLine($"Input a command or 'h' for help, 'q' to quit :");
    line = Console.ReadLine();
    if (line == "q" || string.IsNullOrWhiteSpace(line))
        continue;

    line = line.Trim();
    if (line == "h")
    {
        Console.WriteLine("Supports the following commands:");
        Console.WriteLine("string commands: set, get, del");
        Console.WriteLine("hash commands: hset, hget, hgetall, hlen, hdel");
        Console.WriteLine("list commmands: lpush, rpush, lpop, rpop, llen, lrange");
        continue;
    }

    var arr = line.Split(' ');
    if (arr.Length < 2)
    {
        Console.WriteLine("Unsupported command!");
        continue;
    }

    try
    {

        ProcessCommand(arr);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }

}


void ProcessCommand(string[] arr)
{
    switch (arr[0].ToLower())
    {
        case "set":
            if (arr.Length > 2)
            {
                Console.WriteLine(db.StringSet(arr[1], arr[2]));
            }
            break;
        case "get":
            var t = db.StringGet(arr[1]);
            Console.WriteLine(t.ToString()); ;
            break;
        case "del":
            Console.WriteLine(db.KeyDelete(arr[1]));
            break;

        case "hset":
            if (arr.Length > 2)
            {
                Console.WriteLine(db.HashSet(arr[1], arr[2], arr[3]));
            }
            break;
        case "hget":
            if (arr.Length > 2)
            {
                Console.WriteLine(db.HashGet(arr[1], arr[2]));
            }
            break;

        case "hgetall":
            var items = db.HashGetAll(arr[1]);
            foreach (var item in items)
            {
                Console.WriteLine($"{item.Name}: {item.Value}");
            }
            break;
        case "hlen":
            if (arr.Length > 1)
            {
                Console.WriteLine(db.HashLength(arr[1]));
            }
            break;
        case "hdel":
            if (arr.Length > 2)
            {
                Console.WriteLine(db.HashDelete(arr[1], arr[2]));
            }
            break;

        case "lpush":
            if (arr.Length > 2)
            {
                Console.WriteLine(db.ListLeftPush(arr[1], arr[2]));
            }
            break;
        case "rpush":
            if (arr.Length > 2)
            {
                Console.WriteLine(db.ListRightPush(arr[1], arr[2]));
            }
            break;
        case "lpop":
            if (arr.Length > 1)
            {
                Console.WriteLine(db.ListLeftPop(arr[1]));
            }
            break;
        case "rpop":
            if (arr.Length > 1)
            {
                Console.WriteLine(db.ListRightPop(arr[1]));
            }
            break;
        case "llen":
            if (arr.Length > 1)
            {
                Console.WriteLine(db.ListLength(arr[1]));
            }
            break;
        case "lrange":
            if (arr.Length > 1)
            {
                long start = 0;
                long stop = -1;
                if (arr.Length > 2)
                {
                    start = int.Parse(arr[2]);
                }
                if (arr.Length > 3)
                {
                    stop = int.Parse(arr[3]);
                }
                var list = db.ListRange(arr[1], start, stop);
                foreach (var item in list)
                {
                    Console.WriteLine(item);
                }
            }
            break;

    }
}